`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    22:46:47 11/07/2012 
// Design Name: 
// Module Name:    HFM_CORR_BLOCK 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module HFM_CORR_BLOCK #(parameter LOG_LEN=8, LEN=256, WIDTH=16, OFFSET=0)
(
	input clk_r_x,
	input clk_r_len_x,
	input rst,
	input signed[WIDTH-1:0] in_data_r,
	input signed[WIDTH-1:0] in_data_i,
	output signed[WIDTH-1:0] out_r,
	output signed[WIDTH-1:0] out_i
    );
	 
	 
	 wire[LOG_LEN-1:0] addr_corr_rom;
	 wire signed[WIDTH-1:0] out_corr_rom_r;//rom out to ctr
	 wire signed[WIDTH-1:0] out_corr_rom_i;
	 wire signed[WIDTH-1:0] corr_rom_r;//ctr out
	 wire signed[WIDTH-1:0] corr_rom_i;
	 
	 wire[LOG_LEN-1:0] addr_corr_ram_wr;
	 wire[LOG_LEN-1:0] addr_corr_ram_rd;
	 wire signed[WIDTH-1:0] corr_ram_wr_r;//ctr out to ram
	 wire signed[WIDTH-1:0] corr_ram_wr_i;
	 wire signed[WIDTH-1:0] corr_ram_rd_r;//ram out to ctr
	 wire signed[WIDTH-1:0] corr_ram_rd_i;
	 wire wr_en;
	 wire signed[WIDTH-1:0] corr_ram_r;//ctr out
	 wire signed[WIDTH-1:0] corr_ram_i;
	 
	 wire signed[WIDTH+WIDTH+1+LOG_LEN-1:0] tmp_out_r;//ALU out
	 wire signed[WIDTH+WIDTH+1+LOG_LEN-1:0] tmp_out_i;
	 
	 
	 HFM_CORR_ROM U_corr_rom_r(
	 .clka(clk_r_len_x),
	 .addra(addr_corr_rom),
	 .douta(out_corr_rom_r)
	 );
	 
	 HFM_CORR_ROM U_corr_rom_i(
	 .clka(clk_r_len_x),
	 .addra(addr_corr_rom),
	 .douta(out_corr_rom_i)
	 );
	 
	 ROM_CTR #(LOG_LEN, LEN, WIDTH, OFFSET) U_rom_ctr_r(
		.clk(clk_r_len_x),
		.rst(rst),
		.in_data_r(out_corr_rom_r),
		.in_data_i(out_corr_rom_i),
		.out_data_r(corr_rom_r),
		.out_data_i(corr_rom_i),
		.out_addr(addr_corr_rom)
		);
		
	
	HFM_CORR_RAM U_corr_ram_r(
		.clka(clk_r_len_x),
		.addra(addr_corr_ram_wr),
		.dina(corr_ram_wr_r),
		.wea(wr_en),
		.clkb(clk_r_len_x),
		.addrb(addr_corr_ram_rd),
		.doutb(corr_ram_rd_r)
		);
		
		
	HFM_CORR_RAM U_corr_ram_i(
		.clka(clk_r_len_x),
		.addra(addr_corr_ram_wr),
		.dina(corr_ram_wr_i),
		.wea(wr_en),
		.clkb(clk_r_len_x),
		.addrb(addr_corr_ram_rd),
		.doutb(corr_ram_rd_i)
		);	
		
		
	MEM_WR #(LOG_LEN, LEN, WIDTH) U_corr_ram_wr
	(
		.clk(clk_r_x),
		.rst(rst),
		.in_r(in_data_r),
		.in_i(in_data_i),
		.out_r(corr_ram_wr_r),
		.out_i(corr_ram_wr_i),
		.addr(addr_corr_ram_wr),
		.wr_en(wr_en)
    );
	 
	 
	MEM_RD #(LOG_LEN, LEN, WIDTH) U_corr_ram_rd
	(
		.clk(clk_r_len_x),
		.rst(rst),
		.in_r(corr_ram_rd_r),
		.in_i(corr_ram_rd_i),
		.addr_wr(addr_corr_ram_wr),
		.out_r(corr_ram_r),
		.out_i(corr_ram_i),
		.addr(addr_corr_ram_rd)
    );
		
		
	MUL_SUM_UNIT #(LOG_LEN, LEN, WIDTH) U_corr(
		.clk(clk_r_len_x),
		.rst(rst),
		.a_r(corr_ram_r),
		.a_i(corr_ram_i),
		.b_r(corr_rom_r),
		.b_i(corr_rom_i),
		.out_r(tmp_out_r),
		.out_i(tmp_out_i)
		);
		
	
	 SCALE_UNIT #(WIDTH+WIDTH+1+LOG_LEN, WIDTH, WIDTH+WIDTH+1+LOG_LEN) U_scale_r(
	 .clk(clk_r_x),
	 .rst(rst),
	 .data_in(tmp_out_r),
	 .data_out(out_r)
	 );
	 
	 
	 SCALE_UNIT #(WIDTH+WIDTH+1+LOG_LEN, WIDTH, WIDTH+WIDTH+1+LOG_LEN) U_scale_i(
	 .clk(clk_r_x),
	 .rst(rst),
	 .data_in(tmp_out_i),
	 .data_out(out_i)
	 );

endmodule
